Add "Drag And Drop To Frame" keyword for cross-frame drag-and-drop#1953
Add "Drag And Drop To Frame" keyword for cross-frame drag-and-drop#1953b-vamsipunnam wants to merge 2 commits intorobotframework:masterfrom
Conversation
91af1a0 to
d283eb4
Compare
d283eb4 to
bf869a0
Compare
|
Hi @emanlove ,
All tests are now passing in GitHub Actions. Please take another look when you have a chance. Thanks! |
yuriverweij
left a comment
There was a problem hiding this comment.
Thanks for this PR! it looks very promising, but there are a few things that need to be resolved.
- There is a bug in the try/except which can cause the mouse button to stay down.
- The test fixture (html file) has some problems which can give false positives
- Suggestion: the keyword can be made a bit more generic allowing dragging from frame to frame or default context to frame. (in this case the Note can be removed from the docstring)
- Suggestion: add the following to the docstring/description
After this keyword runs, the browser context is always default content, regardless of the context before the call.
| target_element = self.find_element(target) | ||
|
|
||
| action = ActionChains(self.driver, duration=self.ctx.action_chain_delay) | ||
| action.move_to_element(target_element).release().perform() |
There was a problem hiding this comment.
If the find_element() for frame or target raises an error, the mouse button is still held down. The finally switches context back but never releases. The next action in the suite inherits a held mouse button.
| Standard Drag And Drop Fails When Target Is Inside Frame | ||
| [Documentation] Verifies that the standard Drag And Drop keyword cannot complete this cross-frame scenario. | ||
| Wait Until Page Contains Element id=source timeout=10s | ||
| Run Keyword And Expect Error * Drag And Drop id=source id=target |
There was a problem hiding this comment.
I would not wildcard the error that is expected. This can cause the test to "pass" when any error occurs.
| Drag And Drop To Frame Fails With Invalid Frame | ||
| [Documentation] Verifies that the keyword fails when the frame locator is invalid. | ||
| Wait Until Page Contains Element id=source timeout=10s | ||
| Run Keyword And Expect Error * Drag And Drop To Frame |
There was a problem hiding this comment.
I would not wildcard the error that is expected. This can cause the test to "pass" when any error occurs.
Element with locator 'id=missingFrame' not found
| Drag And Drop To Frame Fails With Invalid Target | ||
| [Documentation] Verifies that the keyword fails when the target element is not found inside the iframe. | ||
| Wait Until Page Contains Element id=source timeout=10s | ||
| Run Keyword And Expect Error * Drag And Drop To Frame |
There was a problem hiding this comment.
I would not wildcard the error that is expected. This can cause the test to "pass" when any error occurs.
Element with locator 'id=missingTarget' not found
|
|
||
| @keyword('Drag And Drop To Frame') | ||
| def drag_and_drop_to_frame( | ||
| self, locator: Locator, target: Locator, frame: Locator, |
There was a problem hiding this comment.
In order to make the keyword more generic it might be worth changing some parts:
def drag_and_drop_across_frames( self, locator: Locator, target: Locator, target_frame: Locator, source_frame: Optional[Locator] = None,
locator: Locator of the source element to drag.target: Locator of the drop target.target_frame: Locator of the iframe containing the target.source_frame: Locator of the iframe containing the source, or None if the source is in the default content.
There was a problem hiding this comment.
Test fixture does not seem to work as intended.
Right now:
When clicking on the "Drag Me!" box, and performing a mouseup (releasing the mouse button anywhere) will trigger "Dropped Successfully", regardless of actually moving/draggint the box.
The test would pass even if move_to_element(target_element) did nothing.
The test would pass even if the frame switch silently failed (as long as a mouseup fires somewhere).
The test would pass if you replaced the whole keyword body with click_and_hold().release() on the source.
The fixture needs to validate that the drop actually lands on the target inside the frame, e.g. using real HTML5 DnD events or at least checking the mouseup coordinates hit the target's bounding box. As written, these tests give false confidence
Summary
This PR adds a new keyword Drag And Drop To Frame that reliably supports dragging an element from the main document into a target element inside an iframe.
Motivation
While automating post-deployment tasks in a Salesforce Service Cloud setup flow, I encountered a limitation where drag-and-drop interactions failed when the drop target resided inside an iframe. The existing keywords could not handle this scenario because the WebDriver action chain loses context when switching into an iframe mid-action.
Real-world scenario: Salesforce Service Cloud application
This limitation aligns with
By introducing this keyword, the drag-and-drop flow can now be reliably automated end-to-end.
Changes:
All acceptance tests pass locally, including the new cross-frame scenarios.
All acceptance tests pass locally (including new ones).
This is a non-trivial enhancement — please add the
acknowledgelabel to #120 for release notes credit. Thank you!